"""
房间 | 业务层
"""

from biz.base_biz import (
    CreatorBase,
    DeleterBase,
    GetterBase,
    UpdatorBase,
)
from biz.family_biz.base import FamilyValidatorBase
from components.global_param import get_user_id
from mapping import FamilyRoomMapping
from models.po import FamilyRoomPO
from models.request import (
    FamilyRoomCreateRequest,
    FamilyRoomDetailRequest,
    FamilyRoomListRequest,
    FamilyRoomUpdateRequest,
)
from models.vo import FamilyRoomDetailVO
from service import (
    FamilyFurnitureService,
    FamilyRoomService,
)
from utils.data_utils.special import ObjectIdStr


class Model:
    """ 模型信息 """

    ID_FIELD: str = "room_id"
    NAME: str = "房间"
    PO = FamilyRoomPO
    SERVICE = FamilyRoomService


class FamilyRoomValidator(FamilyValidatorBase):
    """ 房间 | 校验器 """

    model_id_field = Model.ID_FIELD
    model_name = Model.NAME
    model_po = Model.PO
    model_service = Model.SERVICE
    cited_model_service = FamilyFurnitureService

    # -------------------- validate_xxx --------------------
    @staticmethod
    def validate_room_id(room_id: ObjectIdStr) -> None:
        """ 校验 | 房间 ID """

        from biz.family_biz.home_biz import FamilyHomeValidator

        FamilyHomeValidator.validate_exist(room_id)

    # -------------------- validate_crud --------------------
    @classmethod
    def validate_create(cls, request: FamilyRoomCreateRequest) -> None:
        """
        校验 | 创建

        1. 名称是否存在
        2. 别名是否合法
        3. 房间 ID 是否存在
        """

        cls.validate_union(
            {
                "alias": request.alias,
                "name": request.name,
                "home_id": request.home_id,
                "user_id": get_user_id(),
            },
            cls.validate_name_exist,
            cls.validate_alias,
            cls.validate_room_id,
        )

    @classmethod
    def validate_update(cls, request: FamilyRoomUpdateRequest) -> None:
        """
        校验 | 更新

        1. 房间是否存在
        2. 同 `校验 | 创建`
        """

        cls.validate_union(
            {
                "id": request.room_id,
                "room_id": request.room_id,
                "alias": request.alias,
                "name": request.name,
                "home_id": request.home_id,
                "user_id": get_user_id(),
            },
            cls.validate_exist,
            cls.validate_name_exist,
            cls.validate_alias,
            cls.validate_room_id,
        )

    @classmethod
    def validate_delete(cls, request: FamilyRoomDetailRequest) -> None:
        """
        校验 | 删除

        1. 房间是否存在
        2. 房间是否是当前用户的
        3. 房间是否被引用
        """

        cls.validate_union(
            {
                "id": request.room_id,
                "room_id": request.room_id,
                "user_id": get_user_id(),
            },
            cls.validate_exist,
            cls.validate_mine,
            cls.validate_cited,
        )


class FamilyRoomGetter(GetterBase):
    """ 房间 | 获取器 """

    @classmethod
    def get_list_query(cls, request: FamilyRoomListRequest) -> dict:
        condition = cls.Condition({"user_id": get_user_id()})

        condition.add_eq("home_id", value=request.home_id)
        condition.add_regex("alias", value=request.alias)
        condition.add_regex("description", value=request.description)
        condition.add_regex("name", value=request.name)

        return condition.get_query()


class FamilyRoomCreator(CreatorBase):
    """ 房间 | 创建器 """

    @staticmethod
    def _create_data(request: FamilyRoomCreateRequest) -> FamilyRoomPO:
        """ 创建数据 """

        return FamilyRoomPO(
            **request.model_dump(),
            user_id=get_user_id(),
        )

    @classmethod
    def create(cls, request: FamilyRoomCreateRequest) -> FamilyRoomDetailVO:
        """ 房间 | 创建 """

        FamilyRoomValidator.validate_create(request)
        room_po: FamilyRoomPO = cls._create_data(request)
        cls.version_log(room_po)
        vo: FamilyRoomDetailVO = FamilyRoomMapping.po_2_detail_vo(room_po)

        return vo


class FamilyRoomDeleter(DeleterBase):
    """ 房间 | 删除器 """

    @staticmethod
    def _delete_data(request: FamilyRoomDetailRequest) -> FamilyRoomPO:
        """ 删除数据 """

        old_room_po: FamilyRoomPO = FamilyRoomService.get_one_by_id(request.room_id)
        new_room_po: FamilyRoomPO = old_room_po.model_copy(deep=True)
        FamilyRoomService.delete_one(new_room_po)

        return old_room_po

    @classmethod
    def delete(cls, request: FamilyRoomDetailRequest) -> None:
        """ 删除房间 """

        FamilyRoomValidator.validate_delete(request)
        home: FamilyRoomPO = cls._delete_data(request)
        cls.version_log(home)


class FamilyRoomUpdator(UpdatorBase):
    """ 房间 | 更新器 """

    detail_vo = FamilyRoomDetailVO

    @staticmethod
    def _update_data(request: FamilyRoomUpdateRequest) -> tuple[FamilyRoomPO, FamilyRoomPO]:
        """ 更新数据 """

        old_room_po: FamilyRoomPO = FamilyRoomService.get_one_by_id(request.room_id)
        new_room_po: FamilyRoomPO = old_room_po.model_copy(deep=True)
        new_room_po.update_from_request(request)
        FamilyRoomService.update_one(new_room_po)

        return old_room_po, new_room_po

    @classmethod
    def update(cls, request: FamilyRoomUpdateRequest) -> detail_vo:
        """ 更新房间 """

        FamilyRoomValidator.validate_update(request)
        old_room_po, new_room_po = cls._update_data(request)
        cls.version_log(old_room_po, new_room_po)
        vo: FamilyRoomDetailVO = FamilyRoomMapping.po_2_detail_vo(new_room_po)

        return vo
